package cs342.project1.mathNotebook.xml;

import java.io.*;
import java.util.Collection;

import cs342.project1.mathNotebook.notebook.NotebookEntry;

/**
 * Provides the ability to write notebook entries to a data source
 * @author Jared Schlicht
 * @author Gabrielle DuBois
 */
public abstract class NotebookWriter {
	protected ByteArrayOutputStream out;

	/**
     * Initializes outputstream
     * @param outStream a ByteArrayOutputStream which will be containing info
     */
	public NotebookWriter(ByteArrayOutputStream outStream){
		//in the end this is really only going to work with ByteArrayOutputStreams
		out = outStream;
	}//constructor

    /**
     * Writes notebook entries out to a file. The type of file is determined
     * by the type of object calling the method. An XMLWriter object will create
     * an plain xml file with a .xml appended to the end of the original file
     * name. A CompressionWriter object will create a zipped file
     * with a .gz appended to the end of the original file
     * name. A DESWriter object will create a compressed and zipped file with
     * a .enc appended to the end of the original file name.
     * @param enteries
     * @param fileName
     * @param key
     * @return a boolean siginifying if the save was successful
     */
    public boolean saveFile(final Collection<NotebookEntry> entries, String fileName){
		boolean isSuccessful = true;
		out = this.saveStream(entries);
		byte[] xmlBytes = out.toByteArray();

		try {
			FileOutputStream outFile;

			//TODO: if statement from hell...need to refactor this out
			if (this instanceof CompressionWriter){
				outFile = new FileOutputStream(fileName + ".gz");
				outFile.write(xmlBytes);
				outFile.flush();
				outFile.close();
			}//if (CompressionWriter)
			else if (this instanceof DESWriter){
				outFile = new FileOutputStream(fileName + ".enc");
				outFile.write(xmlBytes);
				outFile.flush();
				outFile.close();
			}//if (CompressionWriter)
			else{
				outFile = new FileOutputStream(fileName + ".xml");
				outFile.write(xmlBytes);
				outFile.flush();
				outFile.close();
			}//else

		} catch (IOException e) {
			System.out.println("Couldn't save file: " + fileName);
			//was NOT successful
			isSuccessful = false;
		}//tryCatch

		return isSuccessful;
    }//saveFile()

    /**
     * Writes notebook entries to ByteArrayOutputStream
     * @param entries a collection of notebook entries to be saved
     * @return A ByteArrayOutputStream object
     */
    public abstract ByteArrayOutputStream saveStream(final Collection<NotebookEntry> entries);

    /**
     * Closes any resources held by this NotebookWriter
     */
    public void close() {
		try {
	   		this.out.close();
		} catch (IOException e) {
			System.out.println("NotebookWriter.close() error: " + e);
		}//tryCatch
    }//close()
}
